﻿using UnityEditor;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

// Translate: Finished
// Debug: 

namespace Assets.Scripts.LDS
{
    class MetaModel
    {

        public MetaModel()
        {
            name = "";
            catName = ""; id = 0; transformation = Matrix4x4.identity; /*material=new Material*/; visible = true; path = ""; textureDir = "";
            frontDir = new Vector3(0, -1, 0); upDir = new Vector3(0, 0, 1); position = new Vector3(0, 0, 0); theta = 0;
            parentPlaneUVH = new Vector3((float)(0.5), (float)0.5, 0);
            isInitLoaded = false; isAlreadyPlaced = false; isSkipped = false; isTransformedByCommand = false; isJustRollbacked = false; isConstraintExtracted = false; isJustReplaced = false;
            isBvhReady = false; zAdjusted = false; isSelected = Convert.ToInt32(false); renderMode = 0;
            explicitAnchorId = -1; layoutPassScore = -100; layoutScore = -100; trialNum = 0;

            //replace for proper selection rendering;
            // isSelected = rand() % 2;
        }

        public MetaModel(MetaModel m)
        {
            name = m.name;
            catName = m.catName;
            id = m.id;
            transformation = m.transformation;

            material = m.material;
            visible = m.visible;
            path = m.path;
            textureDir = m.textureDir;

            frontDir = m.frontDir;  // transformed dir in current scene
            upDir = m.upDir;     // transformed dir in current scene
            position = m.position;  // transformed model pos in current scene; in world frame
            theta = m.theta;  // angle between anchor's front to current model's front; from -pi to pi

            parentPlaneUVH = m.parentPlaneUVH;


            isInitLoaded = m.isInitLoaded; // whether the model is loaded at the beginning
            isAlreadyPlaced = m.isAlreadyPlaced; // whether the model is already placed in the scene
            isSkipped = m.isSkipped; // is skipped for placement due to collision or relation break after trial number of tests

            isTransformedByCommand = m.isTransformedByCommand;

            isJustRollbacked = m.isJustRollbacked; // whether the model is just rollback for placement
            isConstraintExtracted = m.isConstraintExtracted;
            isJustReplaced = m.isJustReplaced; // whether the model is just replaced by another instance

            isBvhReady = m.isBvhReady;  // whether the BVH is ready for collision detection
            zAdjusted = m.zAdjusted;



            isSelected = m.isSelected;
            renderMode = m.renderMode;

            explicitAnchorId = m.explicitAnchorId;

            tempPlacement = new List<float>(m.tempPlacement);  // temp data used for roll back
            tempTransform = m.tempTransform;
            layoutPassScore = m.layoutPassScore;
            layoutScore = m.layoutScore;
            trialNum = m.trialNum;
        }

        public string name;  // file name (hash string) of the model
        public string catName; // category of model
        public int id;
        public Matrix4x4 transformation;  // transform from loaded model to current model

        public Material material;
        public bool visible;
        public string path;
        public string textureDir;

        public Vector3 frontDir;  // transformed dir in current scene
        public Vector3 upDir;     // transformed dir in current scene
        public Vector3 position;  // transformed model pos in current scene; in world frame
        double theta;  // angle between anchor's front to current model's front; from -pi to pi

        public Vector3 parentPlaneUVH;  // UV and height w.r.t to the bbTopPlane and height is not normalized
                                        //public SuppPlaneManager suppPlaneManager;


        public bool isInitLoaded; // whether the model is loaded at the beginning
        public bool isAlreadyPlaced; // whether the model is already placed in the scene
        public bool isSkipped; // is skipped for placement due to collision or relation break after trial number of tests

        public bool isTransformedByCommand;

        public bool isJustRollbacked; // whether the model is just rollback for placement
        public bool isConstraintExtracted;
        public bool isJustReplaced; // whether the model is just replaced by another instance

        public bool isBvhReady;  // whether the BVH is ready for collision detection
        public bool zAdjusted;

        public int isSelected;
        public int renderMode;

        public int explicitAnchorId;

        List<float> tempPlacement = new List<float>();  // temp data used for roll back
        public Matrix4x4 tempTransform;
        public double layoutPassScore;
        public double layoutScore;
        public int trialNum; // trialNum for re-location because of collision

        //			void updateWithTransform(const Matrix4x4 &transMat, Vector3 anchorFrontDir=Vector3(), Vector3 sceneUpDir= Vector3())
        public void updateWithTransform(Matrix4x4 transMat)
        {
            position = transMat * position;
            frontDir = Util.TransformVector(transMat, frontDir);
            upDir = Util.TransformVector(transMat, upDir);

            frontDir.Normalize();
            upDir.Normalize();

            //bbTopPlane.transform(transMat);
            //suppPlaneManager.transformSuppPlanes(transMat);

            transformation = transMat * transformation;

            //if (anchorFrontDir!=Vector3() && sceneUpDir!= Vector3())
            //{
            //	theta = GetRotAngleR(anchorFrontDir, frontDir, sceneUpDir);
            //}

            isBvhReady = false;
        }

    }
    class MetaScene
    {
        public MetaScene()
        {

        }
        public MetaScene(MetaScene m)
        {
            m_metaModellList = Util.CopyList<MetaModel>(m.m_metaModellList);
            m_sceneFormat = m.m_sceneFormat;
            m_sceneFileName = m.m_sceneFileName;
            m_sceneFilePath = m.m_sceneFilePath;
            m_sceneDBPath = m.m_sceneDBPath;
            m_modelRepository = m.m_modelRepository;
        }
        public List<MetaModel> m_metaModellList = new List<MetaModel>();
        public string m_sceneFormat;

        // File info
        public string m_sceneFileName;
        public string m_sceneFilePath;
        public string m_sceneDBPath;
        public string m_modelRepository;

    }
}